package hashset

/*
Copyright @2016 by No.20(zdt3476@163.com)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

var emptyStruct = struct{}{}

type HashSet struct {
	items map[interface{}]struct{}
	size  int
}

// New return a pointer
func New() *HashSet {
	return &HashSet{
		items: make(map[interface{}]struct{}),
		size:  0,
	}
}

// Empty return whether set empty is
func (s *HashSet) Empty() bool {
	return s.Size() == 0
}

// Size return set's size
func (s *HashSet) Size() int {
	return s.size
}

// Add a item to set
func (s *HashSet) Add(item interface{}) {
	s.items[item] = emptyStruct
	s.size++
}

// Clear set
func (s *HashSet) Clear() {
	s.size = 0
	s.items = make(map[interface{}]struct{})
}

// Contains find item exsist
func (s *HashSet) Contains(item interface{}) bool {
	_, find := s.items[item]
	return find
}

// Remove a item from set
func (s *HashSet) Remove(item interface{}) {
	s.size--
	delete(s.items, item)
}

// Values return all items
func (s *HashSet) Values() []interface{} {
	values := make([]interface{}, s.Size())
	idx := 0
	for item := range s.items {
		values[idx] = item
		idx++
	}

	return values
}
